package service

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"

	"soffice/config"
	"soffice/storage"
)

// SaveImageToStorage 保存图片到存储（本地或MinIO）
func SaveImageToStorage(imageData []byte, imagePath string) (string, error) {
	st := storage.GetStorage()
	reader := bytes.NewReader(imageData)

	// 获取content type
	ext := filepath.Ext(imagePath)
	contentType := getImageContentType(ext)

	return st.SaveFile(reader, imagePath, contentType)
}

// CopyFileToStorage 复制文件到存储
func CopyFileToStorage(srcPath, dstPath string) (string, error) {
	// 读取源文件
	file, err := os.Open(srcPath)
	if err != nil {
		return "", fmt.Errorf("打开源文件失败: %v", err)
	}
	defer file.Close()

	st := storage.GetStorage()
	ext := filepath.Ext(dstPath)
	contentType := getImageContentType(ext)

	return st.SaveFile(file, dstPath, contentType)
}

// GetFileURLFromStorage 获取文件访问URL
func GetFileURLFromStorage(filename string) string {
	st := storage.GetStorage()
	return st.GetFileURL(filename)
}

// DeleteFileFromStorage 从存储删除文件
func DeleteFileFromStorage(filename string) error {
	st := storage.GetStorage()
	return st.DeleteFile(filename)
}

// FileExistsInStorage 检查文件是否存在于存储中
func FileExistsInStorage(filename string) (bool, error) {
	st := storage.GetStorage()
	return st.FileExists(filename)
}

// getImageContentType 根据扩展名获取图片Content-Type
func getImageContentType(ext string) string {
	switch ext {
	case ".jpg", ".jpeg":
		return "image/jpeg"
	case ".png":
		return "image/png"
	case ".gif":
		return "image/gif"
	case ".webp":
		return "image/webp"
	case ".svg":
		return "image/svg+xml"
	case ".bmp":
		return "image/bmp"
	default:
		return "application/octet-stream"
	}
}

// EnsureStorageDir 确保存储目录存在（仅用于本地存储）
func EnsureStorageDir(dirPath string) error {
	// 如果使用MinIO，不需要创建目录
	if os.Getenv("STORAGE_TYPE") == "minio" {
		return nil
	}
	return EnsureDirExists(dirPath)
}

// GetStorageBasePath 获取存储基础路径（用于生成相对路径）
func GetStorageBasePath() string {
	if os.Getenv("STORAGE_TYPE") == "minio" {
		return "" // MinIO不需要基础路径
	}
	return "static"
}

// GetStorageBaseURL 获取存储基础URL
func GetStorageBaseURL() string {
	if os.Getenv("STORAGE_TYPE") == "minio" {
		// MinIO会返回完整URL，不需要前缀
		return ""
	}
	apiBasePath := config.GetAPIBasePath()
	return "/" + apiBasePath + "/static"
}

// SaveUploadedFileToStorage 保存上传的文件到存储
func SaveUploadedFileToStorage(src io.Reader, dstPath string) (string, error) {
	st := storage.GetStorage()

	// 如果是本地存储，需要确保目录存在
	if os.Getenv("STORAGE_TYPE") != "minio" {
		dir := filepath.Dir(dstPath)
		if err := EnsureDirExists(dir); err != nil {
			return "", err
		}
	}

	ext := filepath.Ext(dstPath)
	contentType := getImageContentType(ext)

	url, err := st.SaveFile(src, dstPath, contentType)
	if err != nil {
		return "", err
	}

	log.Printf("文件已保存到存储: %s -> %s", dstPath, url)
	return url, nil
}

// GetStorageInstance 获取存储实例（供controller使用）
func GetStorageInstance() storage.Storage {
	return storage.GetStorage()
}
